package net.goutalk.glcs.module.erpModel.caseErpDevice.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.toolkit.MPJWrappers;
import net.goutalk.glcs.common.annotation.GlcsLog;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.model.result.R;
import net.goutalk.glcs.common.page.ConventPage;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.RedisUtil;
import net.goutalk.glcs.common.utils.VoToColumnUtil;
import net.goutalk.glcs.module.erpModel.caseErpDevice.dto.CaseErpDeviceWarnDto;
import net.goutalk.glcs.module.erpModel.caseErpDevice.dto.UpdateCaseErpDeviceWarnDto;
import net.goutalk.glcs.module.erpModel.caseErpDevice.entity.CaseErpDeviceWarn;
import net.goutalk.glcs.module.erpModel.caseErpDevice.service.ICaseErpDeviceWarnService;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.system.entity.DictionaryDetail;
import net.goutalk.glcs.module.system.service.IDictionarydetailService;
import net.goutalk.glcs.module.workflow.utils.WorkFlowUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import net.goutalk.glcs.module.erpModel.caseErpDevice.vo.CaseErpDeviceWarnExportVo;
import net.goutalk.glcs.module.erpModel.caseErpDevice.vo.CaseErpDeviceWarnInfo;
import net.goutalk.glcs.module.erpModel.caseErpDevice.vo.CaseErpDeviceWarnInfoVo;
import net.goutalk.glcs.module.erpModel.caseErpDevice.vo.CaseErpDeviceWarnVo;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备告警【case_erp_device_warn】 前端控制器
 * </p>
 *
 * @author hnyyzy
 * @since 2023-07-10
 */
@RestController
@RequestMapping(GlobalConstant.CASE_ERP_DEVICE+"/caseErpDeviceWarn")
@Api(value = GlobalConstant.CASE_ERP_DEVICE +"/caseErpDeviceWarn", tags = "设备告警")
@AllArgsConstructor
public class CaseErpDeviceWarnController {

    private ICaseErpDeviceWarnService caseErpDeviceWarnService;

    private IDictionarydetailService dictionarydetailService;

    private RedisUtil redisUtil;

    @GetMapping(value = "/page")
    @ApiOperation("设备告警分页")
    public R page(CaseErpDeviceWarnDto dto) {
        if (ObjectUtil.isNotNull(dto.getStartTime()) && ObjectUtil.isNotNull(dto.getEndTime())) {
            dto.setStartTime(WorkFlowUtil.getStartOfDay(dto.getStartTime()));
            dto.setEndTime(WorkFlowUtil.getEndOfDay(dto.getEndTime()));
        }
        IPage<CaseErpDeviceWarnVo> page = caseErpDeviceWarnService.selectJoinListPage(ConventPage.getPage(dto), CaseErpDeviceWarnVo.class,
                MPJWrappers.<CaseErpDeviceWarn>lambdaJoin()
                        .distinct()
                        .orderByDesc(CaseErpDeviceWarn::getCreateDate)
                        .eq(ObjectUtil.isNotEmpty(dto.getTypeId()),CaseErpDeviceWarn::getTypeId,dto.getTypeId())
                        .eq(ObjectUtil.isNotEmpty(dto.getState()),CaseErpDeviceWarn::getState,dto.getState())
                        .between(ObjectUtil.isNotNull(dto.getStartTime()) && ObjectUtil.isNotNull(dto.getEndTime())
                                , CaseErpDeviceWarn::getCreateDate, dto.getStartTime(), dto.getEndTime())
                        .selectAs(DictionaryDetail::getName,CaseErpDeviceWarnVo::getTypeName)
                        .select(CaseErpDeviceWarn::getId)
                        .select(CaseErpDeviceWarn.class, x -> VoToColumnUtil.fieldsToColumns(CaseErpDeviceWarnVo.class).contains(x.getProperty()))
                        .leftJoin(DictionaryDetail.class,DictionaryDetail::getId,CaseErpDeviceWarn::getTypeId));

        PageOutput<CaseErpDeviceWarnVo> pageOutput = ConventPage.getPageOutput(page);
        return R.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询设备告警信息")
    public R info(@RequestParam Long id) {
        CaseErpDeviceWarn caseErpDeviceWarn = caseErpDeviceWarnService.getById(id);
        if (caseErpDeviceWarn == null) {
            R.error("找不到此设备告警！");
        }
        return R.ok(BeanUtil.toBean(caseErpDeviceWarn, CaseErpDeviceWarnInfo.class));
    }

    @GetMapping(value = "/check")
    @ApiOperation(value = "根据id查看告警信息")
    public R check(@RequestParam Long id) {
        CaseErpDeviceWarn caseErpDeviceWarn = caseErpDeviceWarnService.getById(id);
        if (caseErpDeviceWarn == null) {
            R.error("找不到此设备告警！");
        }
        CaseErpDeviceWarnInfoVo caseErpDeviceWarnInfoVo = BeanUtil.toBean(caseErpDeviceWarn, CaseErpDeviceWarnInfoVo.class);
        if (ObjectUtil.isNotEmpty(caseErpDeviceWarn.getWarnLevel())){
            final DictionaryDetail byId = dictionarydetailService.getById(caseErpDeviceWarn.getWarnLevel());
            if (StrUtil.isNotBlank(byId.getName())){
                caseErpDeviceWarnInfoVo.setLevelName(byId.getName());
            }
        }
        return R.ok(caseErpDeviceWarnInfoVo);
    }

    @PutMapping
    @ApiOperation(value = "修改告警信息")
    public R update(@Valid @RequestBody UpdateCaseErpDeviceWarnDto dto) {
        CaseErpDeviceWarn caseErpDeviceWarn = BeanUtil.toBean(dto, CaseErpDeviceWarn.class);
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        String allUserIdStr = StrUtil.join(StringPool.COMMA, dto.getDealUserIds());
        List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
        List<String> names = allUser.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
        caseErpDeviceWarn.setDealUserNames(StrUtil.join(StringPool.COMMA,names));
        caseErpDeviceWarnService.updateById(caseErpDeviceWarn);
        return R.ok(true);
    }

    @DeleteMapping
    @ApiOperation(value = "删除设备告警")
    @GlcsLog(value = "删除设备告警")
    public R delete(@Valid @RequestBody Long id) {
        return R.ok(caseErpDeviceWarnService.removeById(id));
    }

    @PostMapping(value = "/export")
    @ApiOperation(value = "导出")
    @GlcsLog(value = "导出表单数据")
    public ResponseEntity<byte[]> export() {
        List<CaseErpDeviceWarnExportVo> erpDeviceInspectExportVoList = caseErpDeviceWarnService.selectJoinList(CaseErpDeviceWarnExportVo.class,
                MPJWrappers.<CaseErpDeviceWarn>lambdaJoin()
                        .distinct()
                        .selectAs(DictionaryDetail::getName,CaseErpDeviceWarnExportVo::getTypeName)
                        .select(CaseErpDeviceWarn::getId)
                        .select(CaseErpDeviceWarn.class, x -> VoToColumnUtil.fieldsToColumns(CaseErpDeviceWarnExportVo.class).contains(x.getProperty()))
                        .leftJoin(DictionaryDetail.class,DictionaryDetail::getId,CaseErpDeviceWarn::getTypeId));
        for (CaseErpDeviceWarnExportVo caseErpDeviceWarnExportVo : erpDeviceInspectExportVoList) {
            if (ObjectUtil.isNotEmpty(caseErpDeviceWarnExportVo.getWarnLevel())){
                if (caseErpDeviceWarnExportVo.getWarnLevel().equals(1679372259974070274L)){
                    caseErpDeviceWarnExportVo.setLevelName("一级故障");//一级故障
                }else if (caseErpDeviceWarnExportVo.getWarnLevel().equals(1679372325354881026L)){
                    caseErpDeviceWarnExportVo.setLevelName("二级故障");//二级故障
                }else {
                    caseErpDeviceWarnExportVo.setLevelName("三级故障");//三级故障
                }
            }
        }
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, CaseErpDeviceWarnExportVo.class).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(erpDeviceInspectExportVoList);
        return R.fileStream(bot.toByteArray(), "设备告警信息" + ExcelTypeEnum.XLSX.getValue());
    }
}
